package {
    import away3d.containers.View3D;
    import away3d.debug.AwayStats;
    import away3d.lights.DirectionalLight;
    import away3d.lights.LightBase;
    import away3d.materials.methods.ShadingMethodBase;
    import away3d.materials.utils.CubeMap;
    import away3d.primitives.Plane;
    import away3d.primitives.SkyBox;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Vector3D;
    // import away3d.events.AssetEvent;
	/**
	 * TODO
   * - Generated texture bitmap could be much more complex/detailed/rich. 
   *   But it's not worth, since exists terragen-like tools that allows you to do exactly that.
   * - Level of detail heightmap chuncks. The engine should provide some facilities to do that, although.
	 * @author yo
	 */
	public class HeightMapDemo extends Sprite {
        
        // Environment map.
        [Embed(source="../embeds/envMap/mars_positive_x.jpg")]
        private var EnvPosX:Class;
        [Embed(source="../embeds/envMap/mars_positive_y.jpg")]
        private var EnvPosY:Class;
        [Embed(source="../embeds/envMap/mars_positive_z.jpg")]
        private var EnvPosZ:Class;
        [Embed(source="../embeds/envMap/mars_negative_x.jpg")]
        private var EnvNegX:Class;
        [Embed(source="../embeds/envMap/mars_negative_y.jpg")]
        private var EnvNegY:Class;
        [Embed(source="../embeds/envMap/mars_negative_z.jpg")]
        private var EnvNegZ:Class;
        
        [Embed(source="../embeds/water.jpg")]
		    private var rSand : Class;
        
        
        private const ANTIALIAS:int = 4;
        
        
        private var _camController:HoverDragController;
        private var _view:View3D;
        private var _light:LightBase;
        private var _cubeMap:CubeMap;
        private var _plane:Plane;
        private var _shadowMethod : ShadingMethodBase;
        private var _heightMap: HeightMap;
        private var lightAngle:Number = 0;
		
		public function HeightMapDemo():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
            
      // Init stage.
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      stage.frameRate = 60;

      // Init 3D core.
      _view = new View3D();
      addChild(_view);
      _camController = new HoverDragController(_view.camera, stage);
      _camController.radius = 5000;
      
      // Camera
      _view.camera.lens.far = 150000;

      // Show Away3D stats.
      var stats:AwayStats = new AwayStats(_view);
      stats.x = stage.stageWidth - stats.width;
      addChild(stats);
      
      // Lights.
      var ld:Vector3D = new Vector3D(-0.5, -1, -0.5);
      ld.scaleBy(1);
      _light = new DirectionalLight(ld.x, ld.y, ld.z); // DirectionalLight();
      _light.color = 0xFFFFFF;
      _light.specular = 1;
      _light.diffuse = 1;
      _light.castsShadows = true;
      _view.scene.addChild(_light);
      
      // SkyBox
      _cubeMap = new CubeMap(new EnvPosX().bitmapData, new EnvNegX().bitmapData,
          new EnvPosY().bitmapData, new EnvNegY().bitmapData,
          new EnvPosZ().bitmapData, new EnvNegZ().bitmapData);
          
      _view.scene.addChild(new SkyBox(_cubeMap));
      
      var hm:ComplexHeightMap = new ComplexHeightMap(_view, _camController);
            
      stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
      
      _view.antiAlias = ANTIALIAS;
      
      // Start loop
      addEventListener(Event.ENTER_FRAME, enterFrameHandler);
      
      stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
		}
    
    
    private function onMouseMove(e:MouseEvent):void
    {
        if (e.shiftKey)
        {
          (_light as DirectionalLight).direction = new Vector3D(Math.sin(lightAngle), -1, Math.cos(lightAngle));
          lightAngle += 0.01;
        }
    }
        
    
    private function mouseDown(e:MouseEvent ):void
    {
        var camUnproject:Vector3D = _view.camera.unproject(e.stageX, e.stageY);
        camUnproject.normalize();
        trace("camUnproject: " + camUnproject);
                    
        var camPos:Vector3D = _view.camera.position;
        var cameraLookAt:Vector3D = new Vector3D(0, 0, 0);
        var camDir:Vector3D = cameraLookAt.subtract(camPos);
        camDir.normalize();
        
        trace("camPos: " + camPos);
        trace("camDir: " + camDir);
    }
        
        
		
    private function enterFrameHandler(event:Event):void
    {
        _view.render();
    }
        
	}
	
}

